package com.df.springmvc.workflow.deploy.dao;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.MultiInstanceLoopCharacteristics;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.stereotype.Repository;
import com.common.bean.SQLInsertBean;
import com.common.bean.SQLResultBean;
import com.common.bean.SQLUpdateBean;
import com.common.util.SN_GUID;
import com.df.springmvc.workflow.ActicityDao;

/**
 * 本类只做数据库操作处理
 * @author Turner
 */
@Repository
public class DeployManageDao extends ActicityDao{
	/**
	 * *
	 * @param sql
	 *            查询的SQL
	 * @param param_HashMap
	 *            查询参数
	 * @param i
	 *            从第几天开始
	 * @param j
	 *            显示多少条数据
	 * @return
	 * @throws Exception
	 */
	public ArrayList<List<Object>> query(HashMap<String,String> map,Object[] attribute,int i,int j) throws Exception{
		// TODO Auto-generated method stub
		ArrayList<List<Object>> list=new ArrayList<List<Object>>();
		ProcessDefinitionQuery query=repositoryService.createProcessDefinitionQuery();
		if(map.get("defId") != null && !"".equals(map.get("defId"))){
			query=query.processDefinitionKeyLike("%" + map.get("defId") + "%");
		}
		if(map.get("defName") != null && !"".equals(map.get("defName"))){
			query=query.processDefinitionNameLike("%" + map.get("defName") + "%");
		}
		List<ProcessDefinition> defList=query.orderByProcessDefinitionKey().desc().orderByProcessDefinitionVersion().asc().listPage(i,j);
		for(ProcessDefinition def:defList){
			Deployment deployment=repositoryService.createDeploymentQuery().deploymentId(def.getDeploymentId()).singleResult();
			List<Object> objects=new ArrayList<Object>();
			objects.add("");
			objects.add(def.getKey());
			objects.add(def.getName());
			objects.add(def.getDescription());
			objects.add(def.getDeploymentId());
			objects.add(def.getVersion());
			objects.add(DateFormatUtils.format(deployment.getDeploymentTime(),"yyyy-MM-dd HH:mm:ss"));
			objects.add(def.isSuspended()?"暂停":"激活");
			list.add(objects);
		}
		return list;
	}
	public Object suspend(String key) throws Exception{
		try{
			repositoryService.suspendProcessDefinitionByKey(key);
		}catch(Exception e){
			// TODO: handle exception
			if(e.getMessage().contains("already in state 'suspended'")){
				throw new ActivitiException("流程已经暂停");
			}else{
				throw e;
			}
		}finally{
		}
		return "成功";
	}
	public Object active(String key) throws Exception{
		try{
			repositoryService.activateProcessDefinitionByKey(key);
		}catch(Exception e){
			// TODO: handle exception
			if(e.getMessage().contains("already in state 'active'")){
				throw new ActivitiException("流程已经激活");
			}else{
				throw e;
			}
		}finally{
		}
		return "成功";
	}
	@Override
	public Object add(HashMap<String,Object> map) throws Exception{
		String fileId="" + map.get("fileId");
		String filePath="" + map.get("filePath");
		FileInputStream fis=new FileInputStream(filePath);
		try{
			repositoryService.createDeployment().addInputStream(fileId,fis).deploy();
			org.apache.log4j.Logger.getLogger(getClass()).info("部署成功");
			return "部署成功";
		}catch(Exception e){
			// TODO: handle exception
			e.printStackTrace();
		}finally{
			fis.close();
		}
		return "";
	}
	/**
	 * 
	 */
	@Override
	public HashMap<String,Object> view(String deploymentId) throws Exception{
		/** 将生成图片放到文件夹下 */
		// 获取图片资源名称
		List<String> list=processEngine.getRepositoryService().getDeploymentResourceNames(deploymentId);
		// 定义图片资源的名称
		String resourceName="";
		if(list != null && list.size() > 0){
			for(String name:list){
				if(name.indexOf(".png") >= 0){
					resourceName=name;
				}
			}
		}
		// 获取流程定义
		List<ProcessDefinition> processDefinitions=repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).list();
		String defId="";
		String defKey="";
		String defName="";
		String defVersion="";
		String defCategory="";
		String defDesc="";
		String defDepId="";
		for(ProcessDefinition processDefinition:processDefinitions){
			defId=processDefinition.getId();
			defKey=processDefinition.getKey();
			defName=processDefinition.getName();
			defVersion="" + processDefinition.getVersion();
			defCategory=processDefinition.getCategory();
			defDesc=processDefinition.getDescription();
			defDepId=processDefinition.getDeploymentId();
		}
		org.apache.log4j.Logger.getLogger(getClass()).info("defId:" + defId);
		if("".equals(defId)){
			throw new Exception("查询结果失败");
		}
		BpmnModel bpmnModel=repositoryService.getBpmnModel(defId);
		// 得到正在执行的环节
		List<String> activeActivityIds=new ArrayList<String>();
		String activityFontName=processEngine.getProcessEngineConfiguration().getActivityFontName();
		String labelFontName=processEngine.getProcessEngineConfiguration().getLabelFontName();
		InputStream diagramStream=new DefaultProcessDiagramGenerator().generateDiagram(bpmnModel,"png",activeActivityIds,Collections.<String>emptyList(),activityFontName,labelFontName,null,1.0);
		// 获取图片的输入流
		// InputStream in=processEngine.getRepositoryService()..getResourceAsStream(deploymentId,resourceName);
		// 将图片生成到D盘的目录下
		String fileName=Base64.encodeBase64String(resourceName.getBytes()).toUpperCase() + ".png";
		String filePath="temp/workflow/";
		File file=new File(webPath + filePath + fileName);
		// 将输入流的图片写到D盘下
		FileUtils.copyInputStreamToFile(diagramStream,file);
		HashMap<String,Object> map=new HashMap<String,Object>();
		map.put("defId",defId);
		map.put("defKey",defKey);
		map.put("defName",defName);
		map.put("defVersion",defVersion);
		map.put("defCategory",defCategory);
		map.put("defVersion",defVersion);
		map.put("defDesc",defDesc);
		map.put("defDepId",defDepId);
		map.put("resourceName",new File(resourceName).getName());
		map.put("fileName",fileName);
		map.put("filePath",filePath);
		// map.put("file",file);
		return map;
	}
	@Override
	public Object del(HashMap<String,Object> map) throws Exception{
		String depId="" + map.get("depId");
		for(String t:depId.split(",")){
			repositoryService.deleteDeployment(t);
		}
		return "删除成功";
	}
	public Object queryFlowJson(HashMap<String,String> paramMap) throws Exception{
		// TODO Auto-generated method stub
		ArrayList<HashMap<String,Object>> list=new ArrayList<HashMap<String,Object>>();
		String deploymentId=paramMap.get("depId");
		String defId="";
		List<ProcessDefinition> processDefinitions=repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).list();
		for(ProcessDefinition processDefinition:processDefinitions){
			defId=processDefinition.getId();
		}
		BpmnModel bpmnModel=repositoryService.getBpmnModel(defId);
		Process mainProcess=bpmnModel.getMainProcess();
		Collection<FlowElement> flowElements=mainProcess.getFlowElements();
		for(FlowElement flowElement:flowElements){
			if(flowElement instanceof UserTask){
				HashMap<String,Object> map=new HashMap<String,Object>();
				map.put("id",(flowElement.getId()));
				map.put("name",(flowElement.getName()));
				map.put("assignee",((UserTask)flowElement).getAssignee());
				map.put("defId",defId);
				map.put("candidateGroups",((UserTask)flowElement).getCandidateGroups());
				map.put("candidateUsers",((UserTask)flowElement).getCandidateUsers());
				map.put("dueDate",((UserTask)flowElement).getDueDate());
				MultiInstanceLoopCharacteristics loopCharacteristics=((UserTask)flowElement).getLoopCharacteristics();
				if(loopCharacteristics != null){
					map.put("collection",loopCharacteristics.getElementVariable());
				}
				list.add(map);
			}
		}
		return list;
	}
	/**
	 * "map.defId" : defId ,
	 * "map.taskId" : taskId ,
	 * "map.formUrl" : formUrl
	 * @param paramMap
	 * @return
	 * @throws Exception
	 */
	public Object updateFormUrl(HashMap<String,String> paramMap) throws Exception{
		// TODO Auto-generated method stub
		String sql="select wf_proc_task_formUrl from S_WF_Task_Info where  wf_proc_def_id=:wf_proc_def_id and wf_proc_task_id=:wf_proc_task_id";
		HashMap<String,Object> tmp=new HashMap<String,Object>();
		tmp.put("wf_proc_def_id",paramMap.get("defId"));
		tmp.put("wf_proc_task_id",paramMap.get("taskId"));
		SQLResultBean resultBean=querySqlToSQLResultBean(sql,tmp,0,0);
		int size=resultBean.getMapList().size();
		if(size == 0){
			SQLInsertBean bean=new SQLInsertBean("S_WF_Task_Info");
			bean.putColumn("guid",SN_GUID.getUUID());
			bean.putColumn("status","1");
			bean.putColumn("createBy",paramMap.get("userId"));
			bean.putColumn("createTime",new Date());
			bean.putColumn("updateby",paramMap.get("userId"));
			bean.putColumn("updateTime",new Date());
			bean.putColumn("wf_proc_def_id",paramMap.get("defId"));
			bean.putColumn("wf_proc_task_id",paramMap.get("taskId"));
			bean.putColumn("wf_proc_task_formName",paramMap.get("name"));
			bean.putColumn("wf_proc_task_formUrl",paramMap.get("url"));
			bean.putColumn("wf_proc_task_formWidth",paramMap.get("w"));
			bean.putColumn("wf_proc_task_formHeight",paramMap.get("h"));
			excuteSqlBean(bean);
		}else if(size == 1){
			SQLUpdateBean bean=new SQLUpdateBean("S_WF_Task_Info");
			bean.putColumn("status","1");
			bean.putColumn("wf_proc_task_formName",paramMap.get("name"));
			bean.putColumn("wf_proc_task_formUrl",paramMap.get("url"));
			bean.putColumn("wf_proc_task_formWidth",paramMap.get("w"));
			bean.putColumn("wf_proc_task_formHeight",paramMap.get("h"));
			bean.putCondition("wf_proc_def_id",paramMap.get("defId"));
			bean.putCondition("wf_proc_task_id",paramMap.get("taskId"));
			excuteSqlBean(bean);
		}else{
			return "更新失败";
		}
		return "更新成功";
	}
	public Object queryFormInfo(HashMap<String,String> paramMap) throws Exception{
		String sql="select wf_proc_task_formName as name,wf_proc_task_formUrl as url,wf_proc_task_formWidth as w ,wf_proc_task_formHeight as h from S_WF_Task_Info where status=1 and ( wf_proc_def_id=:wf_proc_def_id ) and wf_proc_task_id=:wf_proc_task_id";
		HashMap<String,Object> tmp=new HashMap<String,Object>();
		tmp.put("wf_proc_def_id",paramMap.get("defId"));
		tmp.put("wf_proc_task_id",paramMap.get("taskId"));
		SQLResultBean resultBean=querySqlToSQLResultBean(sql,tmp,0,0);
		ArrayList<HashMap<String,Object>> mapList=resultBean.getMapList();
		for(HashMap<String,Object> hashMap:mapList){
			return hashMap;
		}
		return "";
	}
	/**
	 * 查询上一版文件配置.
	 * @param paramMap
	 * @return
	 * @throws Exception
	 */
	public Object queryFormLastInfo(HashMap<String,String> paramMap) throws Exception{
		String sql="select wf_proc_task_formName as name,wf_proc_task_formUrl as url,wf_proc_task_formWidth as w ,wf_proc_task_formHeight as h from S_WF_Task_Info where status=1 and ( wf_proc_def_id like '%' :wf_proc_def_id '%' ) and wf_proc_task_id=:wf_proc_task_id order by wf_proc_def_id desc";
		HashMap<String,Object> tmp=new HashMap<String,Object>();
		tmp.put("wf_proc_def_id",paramMap.get("defId").split(":")[0]);
		tmp.put("wf_proc_task_id",paramMap.get("taskId"));
		SQLResultBean resultBean=querySqlToSQLResultBean(sql,tmp,0,0);
		ArrayList<HashMap<String,Object>> mapList=resultBean.getMapList();
		for(HashMap<String,Object> hashMap:mapList){
			return hashMap;
		}
		return "";
	}
}
